﻿using System;
using System.Collections.Generic;
using System.Text;
using reactiveBT.Utilities;

namespace reactiveBT.BT
{
    /// <summary>
    /// 随机分支节点，接受int型的权重数组作为输入，默认子节点权重大小为1
    /// 每次Tick随机选中一个新的节点执行。若当前执行的子节点返回Continue，则该次Tick不选中新的子节点，而继续执行原子节点
    /// 向上传递当前子节点的执行结果
    /// </summary>
    public class RandomRoot : Branch
    {
        int[] weight = null;
        int[] AddedWeight = null;
        public RandomRoot(int[] w = null)
        {
            weight = w;
            activeChild = -1;
        }
        public override Branch OpenBranch(params BTNode[] children)
        {
            AddedWeight = new int[children.Length];
            for (int i = 0;i < children.Length;i++)
            {
                int w = 0;
                int previousW = 0;
                if (weight == null || weight.Length <= i)
                {
                    w = 1;
                }
                else
                {
                    w = weight[i];
                }
                
                if (i > 0)
                {
                    previousW = AddedWeight[i - 1];
                }
                AddedWeight[i] = w + previousW;
            }
            return base.OpenBranch(children);
        }
        public override BTState Tick(int BTid)
        {
            if (needToReset)
            {
                this.ResetSelf();
                base.ResetChildren();
                needToReset = false;
            }
            if (activeChild == -1)
            {
                PickNewChild();
            }
            var result = children[activeChild].Tick(BTid);
            switch (result)
            {
                case BTState.Continue:
                    return BTState.Continue;
                default:
                    PickNewChild();
                    return result;
            }
        }
        // TODO 这里可以优化为二分查找
        private void PickNewChild()
        {
            float choice = Utils.Random(0, AddedWeight[AddedWeight.Length - 1]);
            for (int i = 0;i < AddedWeight.Length;i++)
            {
                if (choice - AddedWeight[i] <= 0)
                {
                    activeChild = i;
                    break;
                }
            }

        }
        protected override void ResetSelf()
        {
            activeChild = -1;
        }
    }
}
